<template>
  <div class="cesiumContainer" ref="cesiumContainer"></div>
</template>

<script setup>
import * as Cesium from "cesium";
import { onMounted, ref, reactive, getCurrentInstance } from "vue";
import GUI from "lil-gui";

const cesiumContainer = ref(null);
let model = reactive({});
let scene = reactive({});
let viewer = reactive({});
let billboards = reactive({});
const operation = {
  value: "",
  selectOptions: {
    "基本添加": "addBillboard",
    "详细添加": "setBillboardProperties",
    "改变属性": "changeBillboardPropertes",
    "以米为单位添加": "sizeBillboardInMeters",
    "同时添加多个": "addMultipleBillboards",
    "远近时图的大小阈值": "scaleByDistance",
    "远近时淡入淡出阈值": "fadeByDistance",
    "同一点时进行偏移阈值": "offsetByDistance",
    "添加canvas类型广告牌": "addPointBillboards",
    "将图片绘制在指定的区域": "addMarkerBillboards",
    "更具新的坐标绘制": "inReferenceFrame",
  },
};
let currentInstance = getCurrentInstance();
let gui = new GUI();
gui
  .add(operation, "value", operation.selectOptions)
  .name("加载广告牌")
  .onChange((e) => {
    console.log("广告牌", currentInstance);
    scene.primitives.removeAll();
    switch (e) {
      case "addBillboard":
        addBillboard();
        break;
      case "setBillboardProperties":
        setBillboardProperties();
        break;
      case "changeBillboardPropertes":
        changeBillboardPropertes();
        break;
      case "sizeBillboardInMeters":
        sizeBillboardInMeters();
        break;
      case "addMultipleBillboards":
        addMultipleBillboards();
        break;
      case "scaleByDistance":
        scaleByDistance();
        break;
      case "fadeByDistance":
        fadeByDistance();
        break;
      case "offsetByDistance":
        offsetByDistance();
        break;
      case "addPointBillboards":
        addPointBillboards();
        break;
      case "addMarkerBillboards":
        addMarkerBillboards();
        break;
      case "inReferenceFrame":
        inReferenceFrame();
        break;
    }
  });

// 相当于密钥，申请使用下边链接中的数据时需要用到
Cesium.Ion.defaultAccessToken =
  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyOTQ0YTExZS02N2Y4LTQ2OTMtOWQ4NS1mNzE3ZWMwYTNmNmEiLCJpZCI6NDM1OCwiaWF0IjoxNjI4MTQzMjE1fQ.csECCT352LHVhak2sJlWYXw_gr7U-AqdQ9UMvtfOeg8";

function addBillboard() {
  //创建billboard
  console.log("addBillboard");
  billboards = new Cesium.BillboardCollection();
  billboards.add({
    image: "/public/img/dctx.png",
    position: Cesium.Cartesian3.fromDegrees(119, 40.03883),
  });
  scene.primitives.add(billboards);
}

function setBillboardProperties() {
  console.log("setBillboardProperties");
  billboards = new Cesium.BillboardCollection();
  billboards.add({
    image: "/public/img/dc.png",
    show: true,
    position: Cesium.Cartesian3.fromDegrees(119, 40),
    pixedOffset: new Cesium.Cartesian2(10000, 0), //偏移
    eyeOffest: new Cesium.Cartesian3(0, 0, 0), //眼睛位置
    horizontalOrigin: Cesium.HorizontalOrigin.CENTER, //水平方向
    verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //垂直方向
    scale: .5, //缩放
    // color: Cesium.Color.RED, //颜色 
    rotation: 0, //旋转
    // alignedAxis: Cesium.Cartesian3.ZERO, //对齐轴
    // width: 100,
    // height: 25,
    sizeInMeters: false, //是否以米为单位
  });
  scene.primitives.add(billboards);
}
function changeBillboardPropertes() {
  console.log("changeBillboardPropertes");
  billboards = new Cesium.BillboardCollection();
  let billboard = billboards.add({
    image: "/public/img/dchb.jpg",
  });
  billboard.position = Cesium.Cartesian3.fromDegrees(119, 40, 30000);
  billboard.scale = .1; //缩放
  billboard.color = new Cesium.Color(1, 1, 1, 0.5); 
  scene.primitives.add(billboards);
}

function sizeBillboardInMeters() {
  const center = Cesium.Cartesian3.fromDegrees(119, 40);
  const heading = Cesium.Math.toRadians(50);
  const pitch = Cesium.Math.toRadians(-90);
  const range = 1000;
  viewer.camera.lookAt(
    center,
    new Cesium.HeadingPitchRange(heading, pitch, range)
  );
  const billboards = scene.primitives.add(new Cesium.BillboardCollection());
  billboards.add({
    image: "/public/img/dc.png",
    sizeInMeters: true, //   以米为单位
    position: center,
  });
}
function addMultipleBillboards() {
  console.log("addMultipleBillboards");

  const logoUrl = "/public/img/dctx.png";
  const facilityUrl = "/public/img/dctx.png";
  const dcUrl = "/public/img/dctx.png";
  const billboards = scene.primitives.add(new Cesium.BillboardCollection());
  billboards.add({
    image: logoUrl,
    position: Cesium.Cartesian3.fromDegrees(119, 40),
  });
  billboards.add({
    image: facilityUrl,
    position: Cesium.Cartesian3.fromDegrees(119, 41),
  });
  billboards.add({
    image: dcUrl,
    position: Cesium.Cartesian3.fromDegrees(119, 42),
  });
}

function scaleByDistance() {
  const billboards = scene.primitives.add(new Cesium.BillboardCollection());
  billboards.add({
    image: "/public/img/dc.png",
    position: Cesium.Cartesian3.fromDegrees(119, 40),
    scaleByDistance: new Cesium.NearFarScalar(1500, 1, 1.5e5, 0.2), // 近远比例尺
  });
}
//
function fadeByDistance() {
  const billboards = scene.primitives.add(new Cesium.BillboardCollection());
  billboards.add({
    image: "/public/img/dc.png",
    position: Cesium.Cartesian3.fromDegrees(119, 40),
    translucencyByDistance: new Cesium.NearFarScalar(150, 1, 1.5e7, 0.1), // 淡入淡出
  });
}

function offsetByDistance() {
  Promise.all([
    Cesium.Resource.createIfNeeded("/public/img/dctx.png").fetchImage(),
    Cesium.Resource.createIfNeeded("/public/img/dc.png").fetchImage(),
  ]).then((res) => {
    const billboards = scene.primitives.add(new Cesium.BillboardCollection());
    const facilityHeight = res[0].height;
    console.log("便宜一个图片的位置",facilityHeight)
    billboards.add({
      image: res[0],
      position: Cesium.Cartesian3.fromDegrees(119, 40),
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER, //水平方向
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直方向
    });
    billboards.add({
      image: res[1],
      position: Cesium.Cartesian3.fromDegrees(119, 40),
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER, //水平方向
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直方向
      pixelOffset: new Cesium.Cartesian2(0, -facilityHeight), // 偏移
      pixelOffsetScaleByDistance: new Cesium.NearFarScalar(150, 1, 1.5e6, 0), // 偏移比例尺
      translucencyByDistance: new Cesium.NearFarScalar(1000, 1, 1.5e6, 0), // 1000至1.5e6时完全透明
    });
  });
}

function addPointBillboards() {
  const canvas = document.createElement("canvas");
  canvas.width = 36;
  canvas.height = 36;
  const context2D = canvas.getContext("2d");
  context2D.beginPath();
  context2D.arc(10, 10, 10, 0, Cesium.Math.TWO_PI, true);
  // context2D.fillRect(10,10,20,20);
  // context2D.fillText("马维超", 10, 10);
  context2D.closePath();
  context2D.fillStyle = "rgb(255,255,255)";
  context2D.fill();
  const billboards = scene.primitives.add(new Cesium.BillboardCollection());
  [1, 2, 3].forEach((item) => {
    console.log(Number(item));
    billboards.add({
      image: canvas,
      imageId: "自定义点" + item,
      position: Cesium.Cartesian3.fromDegrees(119, 40 + item),
      color: new Cesium.Color(255, 255, 232+item, 1),
      scale: 0.5,
    });
  });
}

function addMarkerBillboards() {
  const billboars = scene.primitives.add(new Cesium.BillboardCollection());
  billboars.add({
    image: "/public/img/dc.png",
    imageSubRegion: new Cesium.BoundingRectangle(49, 43, 20, 20), // 图片区域
    position: Cesium.Cartesian3.fromDegrees(119, 40),
    color: Cesium.Color.LIME,
  });
  billboars.add({
    image: "/public/img/dc.png",
    imageSubRegion: new Cesium.BoundingRectangle(61, 23, 30, 30), // 图片区域
    position: Cesium.Cartesian3.fromDegrees(119, 41),
    color: new Cesium.Color(0, 0.5, 1, 1),
  });
  billboars.add({
    image: "/public/img/dc.png",
    position: Cesium.Cartesian3.fromDegrees(119, 42),
    imageSubRegion: new Cesium.BoundingRectangle(67, 80, 40, 40),
    color: Cesium.Color.RED,
  });
  billboars.add({
    image: "/public/img/dc.png",
    position: Cesium.Cartesian3.fromDegrees(119, 43),
    imageSubRegion: new Cesium.BoundingRectangle(27, 103, 50, 50),
    color: Cesium.Color.YELLOW,
  });
}
function inReferenceFrame() {
  const billboards = scene.primitives.add(new Cesium.BillboardCollection());
  const center = Cesium.Cartesian3.fromDegrees(119, 40);
  billboards.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);

  billboards.add({
    image: "/public/img/feiji2.png",
    position: new Cesium.Cartesian3(0, 0, 0),
    scale:.1
  });
  billboards.add({
    image: "/public/img/feiji.png",
    position: new Cesium.Cartesian3(1000000, 0, 0),
    scale:.1
  });
  billboards.add({
    image: "/public/img/feiji4.png",
    position: new Cesium.Cartesian3(0, 1000000, 0),
    scale:.1
  });
  billboards.add({
    image: "/public/img/feiji3.png",
    position: new Cesium.Cartesian3(0, 0, 1000000),
    scale:.1
  });
}

onMounted(async () => {
  viewer = new Cesium.Viewer(cesiumContainer.value, {
    baseLayerPicker: false, // 如果设置为false，将不会创建右上角图层按钮。
    fullscreenButton: false, // 如果设置为false，将不会创建右下角全屏按钮。
    vrButton: false, // 如果设置为false，将不会创建VR应用场景
    geocoder: false, // 如果设置为false，将不会创建右上角查询(放大镜)按钮。
    homeButton: false, // 如果设置为false，将不会创建右上角主页(房子)按钮。
    infoBox: false, // 是否显示点击要素之后显示的信息,cesium中的沙盒开关
    sceneModePicker: false, // 如果设置为false，将不会创建右上角投影方式控件(显示二三维切换按钮)。
    selectionIndicator: false, // 获取当选定实体更改时引发的事件。
    navigationHelpButton: false, // 如果设置为false，则不会创建右上角帮助(问号)按钮。
    navigationInstructionsInitiallyVisible: false, // 如果帮助说明最初应该是可见的，则为true；如果直到用户明确单击该按钮，则不显示该说明，否则为false。
    timeline: true, // 如果设置为false，则不会创建正下方时间轴小部件。
    scene3DOnly: true, // 为 true 时，每个几何实例将仅以3D渲染以节省GPU内存。
    animation: true, // 如果设置为false，将不会创建左下角动画小部件。
    shouldAnimate: false, // 默认true ，否则为 false 。此选项优先于设置 Viewer＃clockViewModel 。
    // ps. Viewer＃clockViewModel 是用于控制当前时间的时钟视图模型。我们这里用不到时钟，就把shouldAnimate设为false
    sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode
    requestRenderMode: false, // 启用请求渲染模式，不需要渲染，节约资源吧
    fullscreenElement: document.body, // 全屏时渲染的HTML元素 暂时没发现用处，虽然我关闭了全屏按钮，但是键盘按F11 浏览器也还是会进入全屏
    shadows: true,
  });

  //获取场景对象
  scene = viewer.scene;

  scene.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(119, 40, 1000000),
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-90),
      roll: 0,
    },
  });

  inReferenceFrame();

  const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
  handler.setInputAction((e) => {
    const pick = scene.pick(e.endPosition);
    if (
      Cesium.defined(pick) &&
      Cesium.defined(pick.node) &&
      Cesium.defined(pick.mesh)
    ) {
      console.log(`node:${pick.node.name},mesh:${pick.mesh.name}`);
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
});
</script> 
<style scoped>
.cesiumContainer {
  width: 100%;
  height: 100vh;
}
</style>
